package com.shd.day06;

import com.shd.day03.stream.Dish;

import java.util.*;

import static java.util.stream.Collectors.*;

/**
 * 汇总和规约
 * Created by shanhaodong on 2018/7/30
 */
public class CollectorsInfo {
    public static void main(String[] args) {
        // have a dish list
        List<Dish> menu = Arrays.asList(
                new Dish("pork", false, 800, Dish.Type.MEAT),
                new Dish("beef", false, 700, Dish.Type.MEAT),
                new Dish("chicken", false, 400, Dish.Type.MEAT),
                new Dish("french fries", true, 530, Dish.Type.OTHER),
                new Dish("rice", true, 350, Dish.Type.OTHER),
                new Dish("season fruit", true, 120, Dish.Type.OTHER),
                new Dish("pizza", true, 550, Dish.Type.OTHER),
                new Dish("prawns", false, 300, Dish.Type.FISH),
                new Dish("salmon", false, 450, Dish.Type.FISH)
        );
        // Long howManyDishes = menu.stream().collect(counting());
        // 等同于上面的写法
        long count = menu.stream().count();
        System.out.println("一共有" + count + "种菜");

        // 找出菜谱中热量最高的菜和最低的菜(Optional Java8 容器(有或无)
        Optional<Dish> max = menu.stream().collect(maxBy(Comparator.comparingInt(Dish::getCalories)));
        System.out.println(max.get());

        // 算出菜单的总热量
        Integer sumCal = menu.stream().collect(summingInt(Dish::getCalories));
        System.out.println("菜单的总热量为:" + sumCal);

        // 求出平均值
        Double average = menu.stream().collect(averagingInt(Dish::getCalories));

        // 用summarizingInt工厂一次性返回所有
        IntSummaryStatistics summaryStatistics = menu.stream().collect(summarizingInt(Dish::getCalories));
        summaryStatistics.getSum();
        summaryStatistics.getCount();
        summaryStatistics.getAverage();
        summaryStatistics.getMax();
        summaryStatistics.getMin();
        System.out.println(summaryStatistics);

        // 连接字符串(joining 工厂)
        String dishNames = menu.stream().map(Dish::getName).collect(joining(", "));
        System.out.println(dishNames);

        // 自定义reduce方法(可以代替Collectors,但是会改变原List)
        Integer integer = menu.stream().collect(reducing(0, Dish::getCalories, (i, j) -> i + j));
        System.out.println(integer);

    }

}
